package com.zjcloud.framework.aspectj;

import com.zjcloud.common.utils.SqlLogUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * Mapper方法执行日志切面
 *
 * @author zjcloud
 */
@Aspect
@Component
public class MapperLogAspect {

    /**
     * 定义切点 - 所有Mapper接口的方法
     */
    @Pointcut("execution(* com.zjcloud..*.mapper.*Mapper.*(..))") 
    public void mapperMethodPointcut() {}

    /**
     * 环绕通知，记录Mapper方法执行的开始和结束日志
     *
     * @param joinPoint 连接点
     * @return 方法执行结果
     * @throws Throwable 执行异常
     */
    @Around("mapperMethodPointcut()")
    public Object aroundMapperMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取类名
        String className = joinPoint.getTarget().getClass().getName();
        String simpleClassName = joinPoint.getTarget().getClass().getSimpleName();
        
        // 获取方法名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getName();
        
        // 获取参数
        Object[] args = joinPoint.getArgs();
        
        // 判断是查询方法还是更新方法
        boolean isQuery = isQueryMethod(methodName);
        
        // 记录开始日志
        long startTime = System.currentTimeMillis();
        if (isQuery) {
            SqlLogUtil.logQueryStart(simpleClassName, methodName, args);
        } else {
            SqlLogUtil.logUpdateStart(simpleClassName, methodName, args);
        }
        
        // 执行原方法
        Object result = null;
        try {
            result = joinPoint.proceed();
            return result;
        } finally {
            // 记录结束日志
            if (isQuery) {
                SqlLogUtil.logQueryEnd(simpleClassName, methodName, result, startTime);
            } else {
                int affectedRows = 0;
                if (result instanceof Integer) {
                    affectedRows = (Integer) result;
                } else if (result instanceof Long) {
                    affectedRows = ((Long) result).intValue();
                } else if (result instanceof Boolean) {
                    affectedRows = (Boolean) result ? 1 : 0;
                }
                SqlLogUtil.logUpdateEnd(simpleClassName, methodName, affectedRows, startTime);
            }
        }
    }
    
    /**
     * 判断是否为查询方法
     *
     * @param methodName 方法名
     * @return 是否为查询方法
     */
    private boolean isQueryMethod(String methodName) {
        String lowerMethodName = methodName.toLowerCase();
        return lowerMethodName.startsWith("get") || 
               lowerMethodName.startsWith("find") || 
               lowerMethodName.startsWith("query") || 
               lowerMethodName.startsWith("select") || 
               lowerMethodName.startsWith("count") || 
               lowerMethodName.startsWith("list") || 
               lowerMethodName.startsWith("search") || 
               lowerMethodName.startsWith("check") || 
               lowerMethodName.startsWith("is") || 
               lowerMethodName.startsWith("exists");
    }
}